package com.yds.ydsdatasetbackend.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yds.ydsdatasetbackend.annotation.AuthCheck;
import com.yds.ydsdatasetbackend.common.BaseResponse;
import com.yds.ydsdatasetbackend.common.DeleteRequest;
import com.yds.ydsdatasetbackend.common.ResultUtils;
import com.yds.ydsdatasetbackend.constant.UserConstant;
import com.yds.ydsdatasetbackend.exception.BusinessException;
import com.yds.ydsdatasetbackend.exception.ErrorCode;
import com.yds.ydsdatasetbackend.exception.ThrowUtils;
import com.yds.ydsdatasetbackend.model.dto.file.FileEditRequest;
import com.yds.ydsdatasetbackend.model.dto.file.FileQueryRequest;
import com.yds.ydsdatasetbackend.model.dto.file.FileUpdateRequest;
import com.yds.ydsdatasetbackend.model.dto.file.FileUploadRequest;
import com.yds.ydsdatasetbackend.model.dto.user.*;
import com.yds.ydsdatasetbackend.model.entity.File;
import com.yds.ydsdatasetbackend.model.entity.FileVariables;
import com.yds.ydsdatasetbackend.model.entity.User;
import com.yds.ydsdatasetbackend.model.enums.FileFillEnum;
import com.yds.ydsdatasetbackend.model.vo.FileTagCategory;
import com.yds.ydsdatasetbackend.model.vo.FileVO;
import com.yds.ydsdatasetbackend.model.vo.LoginUserVO;
import com.yds.ydsdatasetbackend.model.vo.UserVO;
import com.yds.ydsdatasetbackend.service.FileService;
import com.yds.ydsdatasetbackend.service.FileTrainService;
import com.yds.ydsdatasetbackend.service.FileVariablesService;
import com.yds.ydsdatasetbackend.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.security.auth.Subject;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/file")
public class FileController {

    @Resource
    private FileService fileService;

    @Resource
    private UserService userService;

    @Resource
    private FileVariablesService fileVariablesService;

    @Resource
    private FileTrainService fileTrainService;


    /**
     * 上传文件（可重新上传）
     */
    @PostMapping("/upload")
//    @SaSpaceCheckPermission(value = SpaceUserPermissionConstant.PICTURE_UPLOAD)
//    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<FileVO> uploadFile(
            @RequestPart("file") MultipartFile multipartFile,
            FileUploadRequest fileUploadRequest,
            HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        FileVO fileVO = fileService.uploadFile(multipartFile, fileUploadRequest, loginUser);
        return ResultUtils.success(fileVO);
    }

    /**
     * 删除文件
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteFile(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        fileService.deleteFile(deleteRequest.getId(), loginUser);
        return ResultUtils.success(true);
    }

    /**
     * 更新图片（仅管理员可用）
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateFile(@RequestBody FileUpdateRequest fileUpdateRequest, HttpServletRequest request) {
        if (fileUpdateRequest == null || fileUpdateRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 将实体类和 DTO 进行转换
        File file = new File();
        BeanUtils.copyProperties(fileUpdateRequest, file);
        // 注意将 list 转为 string
        file.setTags(JSONUtil.toJsonStr(fileUpdateRequest.getTags()));
        // 数据校验
        fileService.validFile(file);
        // 判断是否存在
        long id = fileUpdateRequest.getId();
        File oldFile = fileService.getById(id);
        ThrowUtils.throwIf(oldFile == null, ErrorCode.NOT_FOUND_ERROR);
//        // 补充过审参数
//        User loginUser = userService.getLoginUser(request);
//        fileService.fillReviewParams(file, loginUser);
        // 操作数据库
        boolean result = fileService.updateById(file);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }

    /**
     * 根据 id 获取文件（仅管理员可用）
     */
    @GetMapping("/get")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<File> getFileById(long id, HttpServletRequest request) {
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        // 查询数据库
        File file = fileService.getById(id);
        ThrowUtils.throwIf(file == null, ErrorCode.NOT_FOUND_ERROR);
        // 获取封装类
        return ResultUtils.success(file);
    }

    /**
     * 根据 id 获取文件（封装类）
     */
    @GetMapping("/get/vo")
    public BaseResponse<FileVO> getFileVOById(long id, HttpServletRequest request) {
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        // 查询数据库
        File file = fileService.getById(id);
        ThrowUtils.throwIf(file == null, ErrorCode.NOT_FOUND_ERROR);
        // 空间校验
//        Long spaceId = file.getSpaceId();
//        Space space = null;
//        if (spaceId != null) {
//            boolean hasPermission = StpKit.SPACE.hasPermission(SpaceUserPermissionConstant.PICTURE_VIEW);
//            ThrowUtils.throwIf(!hasPermission, ErrorCode.NO_AUTH_ERROR);
//            // User loginUser = userService.getLoginUser(request);
//            // 改为采用注解鉴权
//                     fileService.checkFileAuth(loginUser, file);
//            space = spaceService.getById(spaceId);
//            ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR, "空间不存在");
//        }
        // 获取权限列表
//        User loginUser = userService.getLoginUser(request);
//        List<String> permissionList = spaceUserAuthManager.getPermissionList(space, loginUser);
        FileVO fileVO = fileService.getFileVO(file, request);
//        fileVO.setPermissionList(permissionList);
        // 获取封装类
        return ResultUtils.success(fileVO);
    }

    /**
     * 编辑文件
     */
    @PostMapping("/edit")
    @AuthCheck(mustRole = UserConstant.USER_LOGIN_STATE)
    public BaseResponse<Boolean> editFile(@RequestBody FileEditRequest fileEditRequest, HttpServletRequest request) {
        if (fileEditRequest == null || fileEditRequest.getId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        fileService.editFile(fileEditRequest, loginUser);
        return ResultUtils.success(true);
    }

    /**
     * 分页获取文件列表（仅管理员可用）
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<File>> listFileByPage(@RequestBody FileQueryRequest fileQueryRequest, HttpServletRequest request) {

        long current = fileQueryRequest.getCurrent();
        long size = fileQueryRequest.getPageSize();
        // 查询数据库
        Page<File> filePage = fileService.page(new Page<>(current, size),
                fileService.getQueryWrapper(fileQueryRequest));
        return ResultUtils.success(filePage);
    }

    /**
     * 分页获取图片列表（封装类）
     */
    @PostMapping("/list/page/vo")
    public BaseResponse<Page<FileVO>> listFileVOByPage(@RequestBody FileQueryRequest fileQueryRequest,
                                                       HttpServletRequest request) {
        // 只允许展示公共成功上传文件
        fileQueryRequest.setFillStatus(FileFillEnum.SUCCEED.getValue());

        long current = fileQueryRequest.getCurrent();
        long size = fileQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
//        Long spaceId = fileQueryRequest.getSpaceId();
//        if (spaceId == null) {
//            // 公开图库
//            // 普通用户默认只能看到审核通过数据
//            fileQueryRequest.setReviewStatus(FileReviewStatusEnum.PASS.getValue());
//            fileQueryRequest.setNullSpaceId(true);
//        } else {
//            boolean hasPermission = StpKit.SPACE.hasPermission(SpaceUserPermissionConstant.PICTURE_VIEW);
//            ThrowUtils.throwIf(!hasPermission, ErrorCode.NO_AUTH_ERROR);
////            // 私有空间
////            User loginUser = userService.getLoginUser(request);
////            Space space = spaceService.getById(spaceId);
////            ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR, "空间不存在");
////            if (!loginUser.getId().equals(space.getUserId())) {
////                throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "没有空间权限");
////            }
//        }

        // 查询数据库
        Page<File> filePage = fileService.page(new Page<>(current, size),
                fileService.getQueryWrapper(fileQueryRequest));
        // 获取封装类
        return ResultUtils.success(fileService.getFileVOPage(filePage, request));
    }

    /**
     * 分页获取图片列表（封装类）
     */
    @PostMapping("/list/page/my")
    public BaseResponse<Page<FileVO>> listFileMyByPage(@RequestBody FileQueryRequest fileQueryRequest,
                                                       HttpServletRequest request) {
        // 只允许展示公共成功上传文件
        User loginUser = userService.getLoginUser(request);
        fileQueryRequest.setUserId(loginUser.getId());

        long current = fileQueryRequest.getCurrent();
        long size = fileQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);

        // 查询数据库
        Page<File> filePage = fileService.page(new Page<>(current, size),
                fileService.getQueryWrapper(fileQueryRequest));
        // 获取封装类
        return ResultUtils.success(fileService.getFileVOPage(filePage, request));
    }

    @GetMapping("/tag_category")
    public BaseResponse<FileTagCategory> listFileTagCategory() {
        FileTagCategory fileTagCategory = new FileTagCategory();
        List<String> tagList = Arrays.asList("热门", "图像", "文本", "时间序列", "序列", "表格", "工程", "生物学", "化学");
        List<String> categoryList = Arrays.asList("默认", "分类", "回归", "聚类");
        fileTagCategory.setTagList(tagList);
        fileTagCategory.setCategoryList(categoryList);
        return ResultUtils.success(fileTagCategory);
    }

}
